package com.assessment.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.assessment.common.api.ResultCode;
import com.assessment.common.exception.BusinessException;
import com.assessment.model.dto.AssessmentRecordDTO;
import com.assessment.model.entity.*;
import com.assessment.model.vo.AssessmentItemVO;
import com.assessment.model.vo.AssessmentResultVO;
import com.assessment.model.vo.AssessmentTaskVO;
import com.assessment.repository.*;
import com.assessment.service.AssessmentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 评测服务实现类
 */
@Service
@Slf4j
public class AssessmentServiceImpl implements AssessmentService {

    @Autowired
    private AssessmentPeriodRepository periodRepository;

    @Autowired
    private AssessmentTaskRepository taskRepository;

    @Autowired
    private AssessmentRecordRepository recordRepository;

    @Autowired
    private AssessmentResultRepository resultRepository;

    @Autowired
    private TeacherRepository teacherRepository;

    @Override
    public AssessmentPeriod getCurrentPeriod() {
        return periodRepository.getCurrentPeriod();
    }

    @Override
    public List<AssessmentTaskVO> getTeacherTasks(Integer teacherId, Integer periodId) {
        // 1. 获取教师的评测任务
        List<AssessmentRelation> relations = taskRepository.getTeacherTasks(teacherId, periodId);
        if (CollUtil.isEmpty(relations)) {
            return new ArrayList<>();
        }

        // 2. 转换为VO对象
        List<AssessmentTaskVO> tasks = new ArrayList<>();
        for (AssessmentRelation relation : relations) {
            AssessmentTaskVO taskVO = new AssessmentTaskVO();
            taskVO.setRelationId(relation.getId());
            taskVO.setAssesseeId(relation.getAssesseeId());
            taskVO.setAssesseeName(relation.getAssesseeName());

            // 3. 获取教师部门和职位信息
            Teacher teacher = teacherRepository.getTeacherById(relation.getAssesseeId());
            if (teacher != null) {
                Department department = teacherRepository.getDepartmentById(teacher.getDepartmentId());
                Position position = teacherRepository.getPositionById(teacher.getPositionId());
                if (department != null) {
                    taskVO.setAssesseeDepartment(department.getName());
                }
                if (position != null) {
                    taskVO.setAssesseePosition(position.getName());
                }
            }

            // 4. 设置其他属性
            taskVO.setRuleId(relation.getRuleId());
            taskVO.setPeriodId(relation.getPeriodId());
            taskVO.setAssessStatus(relation.getAssessStatus());

            // 5. 获取周期信息
            AssessmentPeriod period = periodRepository.getById(relation.getPeriodId());
            if (period != null) {
                taskVO.setPeriodName(period.getName());
                taskVO.setStartTime(period.getStartTime());
                taskVO.setEndTime(period.getEndTime());
            }

            tasks.add(taskVO);
        }

        return tasks;
    }

    @Override
    public AssessmentTaskVO getTaskDetail(Integer relationId) {
        // 1. 获取评测关系
        AssessmentRelation relation = taskRepository.getTaskById(relationId);
        if (relation == null) {
            throw new BusinessException(ResultCode.ASSESSMENT_RELATION_NOT_FOUND);
        }

        // 2. 构建评测任务VO
        AssessmentTaskVO taskVO = new AssessmentTaskVO();
        BeanUtil.copyProperties(relation, taskVO);
        taskVO.setRelationId(relation.getId());
        taskVO.setAssesseeId(relation.getAssesseeId());
        taskVO.setAssesseeName(relation.getAssesseeName());

        // 3. 获取教师部门和职位信息
        Teacher teacher = teacherRepository.getTeacherById(relation.getAssesseeId());
        if (teacher != null) {
            Department department = teacherRepository.getDepartmentById(teacher.getDepartmentId());
            Position position = teacherRepository.getPositionById(teacher.getPositionId());
            if (department != null) {
                taskVO.setAssesseeDepartment(department.getName());
            }
            if (position != null) {
                taskVO.setAssesseePosition(position.getName());
            }
        }

        // 4. 获取周期信息
        AssessmentPeriod period = periodRepository.getById(relation.getPeriodId());
        if (period != null) {
            taskVO.setPeriodName(period.getName());
            taskVO.setStartTime(period.getStartTime());
            taskVO.setEndTime(period.getEndTime());
        }

        // 5. 获取评测项目
        List<AssessmentItem> items = taskRepository.getAssessmentItems(relation.getRuleId());

        // 6. 获取已提交的评测记录
        Map<Integer, AssessmentRecord> recordMap = null;
        if (relation.getAssessStatus() == 1) { // 已评分
            List<AssessmentRecord> records = recordRepository.getRecordsByRelationId(relationId);
            recordMap = records.stream().collect(Collectors.toMap(
                    AssessmentRecord::getItemId, record -> record));
        }

        // 7. 构建评测项目VO列表
        List<AssessmentItemVO> itemVOs = new ArrayList<>();
        for (AssessmentItem item : items) {
            AssessmentItemVO itemVO = new AssessmentItemVO();
            itemVO.setItemId(item.getId());
            itemVO.setItemName(item.getName());
            itemVO.setDescription(item.getDescription());
            itemVO.setCategoryId(item.getCategoryId());
            itemVO.setMaxScore(item.getMaxScore());
            itemVO.setSort(item.getSort());

            // 如果已评分，设置评分和评语
            if (recordMap != null && recordMap.containsKey(item.getId())) {
                AssessmentRecord record = recordMap.get(item.getId());
                itemVO.setScore(record.getScore());
                itemVO.setComments(record.getComments());
                itemVO.setCategoryName(record.getCategoryName());
            }

            itemVOs.add(itemVO);
        }

        taskVO.setItems(itemVOs);

        return taskVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean submitAssessment(AssessmentRecordDTO recordDTO, Integer teacherId) {
        // 1. 校验评测关系
        Integer relationId = recordDTO.getRelationId();
        AssessmentRelation relation = taskRepository.getTaskById(relationId);
        if (relation == null) {
            throw new BusinessException(ResultCode.ASSESSMENT_RELATION_NOT_FOUND);
        }

        // 2. 校验评测状态
        if (relation.getAssessStatus() == 1) {
            throw new BusinessException(ResultCode.ASSESSMENT_COMPLETED);
        }

        // 3. 校验评测项目
        List<AssessmentItem> items = taskRepository.getAssessmentItems(relation.getRuleId());
        Map<Integer, AssessmentItem> itemMap = items.stream().collect(Collectors.toMap(
                AssessmentItem::getId, item -> item));

        List<AssessmentRecordDTO.ItemScore> itemScores = recordDTO.getItemScores();
        if (CollUtil.isEmpty(itemScores)) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "评分项不能为空");
        }

        // 4. 记录评测记录
        List<AssessmentRecord> records = new ArrayList<>();
        for (AssessmentRecordDTO.ItemScore itemScore : itemScores) {
            Integer itemId = itemScore.getItemId();
            AssessmentItem item = itemMap.get(itemId);
            if (item == null) {
                throw new BusinessException(ResultCode.ASSESSMENT_ITEM_NOT_FOUND);
            }

            // 校验分数范围
            BigDecimal score = itemScore.getScore();
            if (score.compareTo(BigDecimal.ZERO) < 0 || score.compareTo(item.getMaxScore()) > 0) {
                throw new BusinessException(ResultCode.SCORE_OUT_OF_RANGE);
            }

            // 创建评测记录
            AssessmentRecord record = new AssessmentRecord();
            record.setRelationId(relationId);
            record.setItemId(itemId);
            record.setAssessorId(teacherId);
            record.setAssesseeId(relation.getAssesseeId());
            record.setPeriodId(relation.getPeriodId());
            record.setScore(score);
            record.setComments(itemScore.getComments());

            // 设置冗余字段
            Teacher assessor = teacherRepository.getTeacherById(teacherId);
            if (assessor != null) {
                record.setAssessorName(assessor.getName());
            }

            Teacher assessee = teacherRepository.getTeacherById(relation.getAssesseeId());
            if (assessee != null) {
                record.setAssesseeName(assessee.getName());
            }

            records.add(record);
        }

        // 5. 保存评测记录
        boolean result = recordRepository.batchSaveRecords(records);

        // 6. 更新评测关系状态
        if (result) {
            result = taskRepository.updateTaskStatus(relationId, 1);
        }

        return result;
    }

    @Override
    public AssessmentResultVO getTeacherResult(Integer teacherId, Integer periodId) {
        // 1. 查询评测结果
        AssessmentResult overallResult = resultRepository.getTeacherOverallResult(teacherId, periodId);
        if (overallResult == null) {
            return null;
        }

        // 2. 构建结果VO
        AssessmentResultVO resultVO = new AssessmentResultVO();
        BeanUtil.copyProperties(overallResult, resultVO);

        // 3. 查询分类评测结果
        List<AssessmentResult> categoryResults = resultRepository.getTeacherCategoryResults(teacherId, periodId);
        if (CollUtil.isNotEmpty(categoryResults)) {
            List<AssessmentResultVO.CategoryScore> categoryScores = new ArrayList<>();
            for (AssessmentResult result : categoryResults) {
                AssessmentResultVO.CategoryScore categoryScore = new AssessmentResultVO.CategoryScore();
                categoryScore.setCategoryId(result.getCategoryId());
                categoryScore.setCategoryName(result.getCategoryName());
                categoryScore.setAvgScore(result.getAvgScore());
                categoryScores.add(categoryScore);
            }
            resultVO.setCategoryScores(categoryScores);
        }

        return resultVO;
    }

    @Override
    public List<AssessmentResultVO> getDepartmentResults(Integer departmentId, Integer periodId) {
        // 1. Validate parameters
        if (departmentId == null || periodId == null) {
            return new ArrayList<>();
        }

        // 2. Query assessment results
        List<AssessmentResult> results = resultRepository.getDepartmentResults(departmentId, periodId);
        if (CollUtil.isEmpty(results)) {
            return new ArrayList<>();
        }

        // 3. Convert to VO objects
        List<AssessmentResultVO> resultVOs = new ArrayList<>();
        for (AssessmentResult result : results) {
            AssessmentResultVO resultVO = new AssessmentResultVO();
            BeanUtil.copyProperties(result, resultVO);
            resultVOs.add(resultVO);
        }

        return resultVOs;
    }

    @Override
    public List<AssessmentResultVO> getAllResults(Integer periodId) {
        // 1. Validate parameter
        if (periodId == null) {
            return new ArrayList<>();
        }

        // 2. Query all assessment results
        List<AssessmentResult> results = resultRepository.getAllResults(periodId);
        if (CollUtil.isEmpty(results)) {
            return new ArrayList<>();
        }

        // 3. Convert to VO objects
        List<AssessmentResultVO> resultVOs = new ArrayList<>();
        for (AssessmentResult result : results) {
            AssessmentResultVO resultVO = new AssessmentResultVO();
            BeanUtil.copyProperties(result, resultVO);
            resultVOs.add(resultVO);
        }

        return resultVOs;
    }
}
